from typing import Any, Callable, ParamSpec, TypeVar
from ducktape.errors import DucktapeError as DucktapeError

_F = TypeVar("_F", bound=Callable[..., object])

class Mark:
    @staticmethod
    def mark(fun, mark) -> None: ...
    @staticmethod
    def marked(f, mark) -> bool: ...
    @staticmethod
    def clear_marks(f) -> None: ...
    @property
    def name(self) -> str: ...
    def apply(self, seed_context, context_list): ...
    def __eq__(self, other): ...

class Ignore(Mark):
    injected_args: dict

    def __init__(self, **kwargs) -> None: ...
    @property
    def name(self) -> str: ...
    def apply(self, seed_context, context_list): ...
    def __eq__(self, other): ...

class IgnoreAll(Ignore):
    injected_args: None

    def __init__(self) -> None: ...

class Matrix(Mark):
    injected_args: dict

    def __init__(self, **kwargs) -> None: ...
    @property
    def name(self) -> str: ...
    def apply(self, seed_context, context_list): ...
    def __eq__(self, other): ...

class Defaults(Mark):
    injected_args: dict

    def __init__(self, **kwargs) -> None: ...
    @property
    def name(self) -> str: ...
    def apply(self, seed_context, context_list): ...
    def __eq__(self, other): ...

class Parametrize(Mark):
    injected_args: dict

    def __init__(self, **kwargs) -> None: ...
    @property
    def name(self) -> str: ...
    def apply(self, seed_context, context_list): ...
    def __eq__(self, other): ...

class Env(Mark):
    injected_args: dict
    should_ignore: bool

    def __init__(self, **kwargs) -> None: ...
    @property
    def name(self) -> str: ...
    def apply(self, seed_context, context_list): ...
    def __eq__(self, other): ...

PARAMETRIZED: Parametrize
MATRIX: Matrix
DEFAULTS: Defaults
IGNORE: Ignore
ENV: Env

def parametrized(f) -> bool: ...
def ignored(f) -> bool: ...
def is_env(f) -> bool: ...
def cartesian_product_dict(d: dict) -> list: ...

P = ParamSpec("P")
T = TypeVar("T")

PassDecorator = Callable[[Callable[P, T]], Callable[P, T]]
"""
A decorator that returns the function as is, without any modifications.
This doesn't appear in the source but is how many decorators behave in
this package as they only have the side effect of adding a Mark without
changing the function signature.
"""

def matrix(**kwargs: Any) -> PassDecorator[P, T]: ...
def defaults(**kwargs: Any) -> PassDecorator[P, T]: ...
def parametrize(**kwargs: Any) -> PassDecorator[P, T]: ...
def ignore(*args, **kwargs: Any) -> PassDecorator[P, T]: ...
def env(**kwargs: Any) -> PassDecorator[P, T]: ...
def _inject(*args, **kwargs): ...
